package com.smsc.headend.task.engine.mapper;

import com.baomidou.mybatisplus.annotation.SqlParser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.smsc.headend.module.data.entity.RdMeterReadsLp;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * @author liangli
 * @date 2020/10/21
 */
public interface RdMeterReadsLpMapper extends BaseMapper<RdMeterReadsLp> {

//    @Select("SELECT METER_ID, DATA_ITEM_ID, TV, VALUE, VALIDITY, SRC, LP_DATA_ITEM_ID, TV_UPDATE FROM ( SELECT TMP.*, ROWNUM ROW_ID FROM ( SELECT METER_ID, DATA_ITEM_ID, TV, VALUE, VALIDITY, SRC, LP_DATA_ITEM_ID, TV_UPDATE FROM RD_METER_READS_LP WHERE (TV BETWEEN #{startTime} AND #{endTime}) ) TMP WHERE ROWNUM <= #{pageSize}) WHERE ROW_ID > #{page}")
//    @ResultType(RdMeterReadsLp.class)
//    List<RdMeterReadsLp> getPageData(@Param("startTime") String startTime, @Param("endTime") String endTime, @Param("pageSize") long size, @Param("page") long page);

    List<RdMeterReadsLp> getList(Long startTime, Long endTime, Long lpDataItemId, List<Long> meterIds);

//    @Update("MERGE INTO RD_METER_READS_LP r  " +
//            "<foreach collection=\"list\" item=\"item\" index=\"index\" separator=\"UNION ALL\" open=\"(\" close=\")\">  " +
//            "SELECT #{item.meterId,jdbcType=NUMERIC} meterId, #{item.src,jdbcType=NUMERIC} src, #{item.tv,jdbcType=NUMERIC} tv, #{item.dataItemId,jdbcType=NUMERIC} dataItemId, #{item.lpDataItemId,jdbcType=NUMERIC} lpDataItemId, #{item.value,jdbcType=VARCHAR} value, #{item.validity,jdbcType=NUMERIC} validity, #{item.tvUpdate,jdbcType=NUMERIC} tvUpdate FROM DUAL  " +
//            "</foreach>  " +
//            " ON (r.LP_DATA_ITEM_ID = b.lpDataItemId and r.DATA_ITEM_ID = b.dataItemId and r.METER_ID = b.meterId and r.tv = b.tv)  " +
//            " WHEN NOT MATCHED THEN INSERT(METER_ID, SRC, TV, DATA_ITEM_ID, LP_DATA_ITEM_ID, VALUE, VALIDITY, TV_UPDATE) VALUES ( b.meterId, b.src, b.tv, b.dataItemId, b.lpDataItemId, b.value, b.validity, b.tvUpdate)  " +
//            " WHEN MATCHED THEN UPDATE SET VALUE=b.value, SRC=b.src, VALIDITY=b.validity, TV_UPDATE=b.tvUpdate")
//    @ResultType(Integer.class)
//    @SqlParser(filter = true)
//    Object batchSaveLp(@Param("list") List<RdMeterReadsLp> readsLps,@Param("lpTableName") String shardingTableName);

//    @Insert("INSERT /*IGNORE_ROW_ON_DUPKEY_INDEX(LP_DATA_ITEM_ID, DATA_ITEM_ID, METER_ID, TV)*/  INTO RD_METER_READS_LP (METER_ID, SRC, TV, DATA_ITEM_ID, LP_DATA_ITEM_ID, VALUE, VALIDITY, TV_UPDATE) SELECT * FROM (" +
//            "<foreach collection=\"list\" item=\"item\" index=\"index\" separator=\"UNION ALL\">  " +
//            "SELECT #{item.meterId,jdbcType=NUMERIC} METER_ID, #{item.src,jdbcType=NUMERIC} SRC, #{item.tv,jdbcType=NUMERIC} TV, #{item.dataItemId,jdbcType=NUMERIC} DATA_ITEM_ID, #{item.lpDataItemId,jdbcType=NUMERIC} LP_DATA_ITEM_ID, #{item.value,jdbcType=VARCHAR} VALUE, #{item.validity,jdbcType=NUMERIC} VALIDITY, #{item.tvUpdate,jdbcType=NUMERIC} TV_UPDATE FROM DUAL  " +
//            "</foreach> ) t")
//    @ResultType(Integer.class)
//    @SqlParser(filter = true)
//    Object batchSaveLp(@Param("list") List<RdMeterReadsLp> readsLps);


//    @Update("    MERGE INTO RD_METER_READS_LP A " +
//            " USING (SELECT #{meterId} AS METER_ID, #{src} AS SRC, #{tv} AS TV, #{dataItemId} AS DATA_ITEM_ID, #{lpDataItemId} AS LP_DATA_ITEM_ID, #{value} AS VALUE, #{validity} AS VALIDITY,#{tvUpdate} AS TV_UPDATE FROM DUAL) B ON ( A.LP_DATA_ITEM_ID=B.LP_DATA_ITEM_ID AND A.DATA_ITEM_ID=B.DATA_ITEM_ID AND A.TV=B.TV AND A.METER_ID =B.METER_ID) " +
//            " WHEN MATCHED THEN UPDATE SET A.VALUE=B.VALUE, A.SRC=B.SRC, A.VALIDITY=B.VALIDITY, A.TV_UPDATE=B.TV_UPDATE " +
//            " WHEN NOT MATCHED THEN INSERT (METER_ID, SRC, TV, DATA_ITEM_ID, LP_DATA_ITEM_ID, VALUE, VALIDITY, TV_UPDATE) " +
//            " VALUES (B.METER_ID, B.SRC, B.TV, B.DATA_ITEM_ID, B.LP_DATA_ITEM_ID, B.VALUE, B.VALIDITY, B.TV_UPDATE)")
//    @SqlParser(filter = true)
//    void mergeInto(RdMeterReadsLp rdMeterReadsLp);


//    @Update(" INSERT /*IGNORE_ROW_ON_DUPKEY_INDEX(RD_METER_READS_LP(LP_DATA_ITEM_ID, DATA_ITEM_ID, METER_ID, TV))*/ INTO RD_METER_READS_LP (METER_ID, SRC, TV, DATA_ITEM_ID, LP_DATA_ITEM_ID, VALUE, VALIDITY, TV_UPDATE) " +
//            " VALUES (#{meterId}, #{src}, #{tv}, #{dataItemId} , #{lpDataItemId} , #{value} , #{validity} ,#{tvUpdate})")
//    @SqlParser(filter = true)
//    void insertIgnore(RdMeterReadsLp rdMeterReadsLp);

    @Insert("INSERT INTO RD_METER_READS_LP (meter_id, src, tv, data_item_id, lp_data_item_id, value, validity, tv_update) " +
            " VALUES (#{meterId}, #{src}, #{tv}, #{dataItemId} , #{lpDataItemId} , #{value} , #{validity} ,#{tvUpdate})")
    void insertNormal(RdMeterReadsLp rdMeterReadsLp);


    @Select("<script>SELECT METER_ID, DATA_ITEM_ID, TV, VALUE, VALIDITY, SRC, LP_DATA_ITEM_ID, TV_UPDATE FROM RD_METER_READS_LP WHERE LP_DATA_ITEM_ID = #{lpDataItemId} " +
            "AND METER_ID = #{meterId}" +
//            "AND METER_ID IN <foreach collection=\"meterIds\" item=\"meterId\" index=\"index\" separator=\",\" open=\"(\" close=\")\">#{meterId}</foreach>" +
            "AND TV BETWEEN #{startTv} AND #{endTv}" +
            "</script>")
    IPage<RdMeterReadsLp> getPageRdMeterReadsLp(Page pa, @Param("meterId") Long meterId, @Param("lpDataItemId") Long lpDataItemId, @Param("startTv") Long startTv, @Param("endTv") Long endTv);


    @Select("<script>SELECT METER_ID, DATA_ITEM_ID, TV, VALUE, VALIDITY, SRC, LP_DATA_ITEM_ID, TV_UPDATE FROM RD_METER_READS_LP WHERE LP_DATA_ITEM_ID = #{lpDataItemId} " +
//            "AND METER_ID = #{meterId}" +
            "AND METER_ID IN <foreach collection=\"meterIds\" item=\"meterId\" index=\"index\" separator=\",\" open=\"(\" close=\")\">#{meterId}</foreach>" +
            "AND TV BETWEEN #{startTv} AND #{endTv}" +
            "</script>")
    IPage<RdMeterReadsLp> getPageRdMeterReadsLpByIds(Page pa, @Param("meterIds") List<Long> meterIds, @Param("lpDataItemId") Long lpDataItemId, @Param("startTv") Long startTv, @Param("endTv") Long endTv);


    Integer countByTv(@Param("lpDataItemId") Long lpDataItemId, @Param("meterId") Long meterId, @Param("startTv") Long startTv, @Param("endTv") Long endTv);


    Integer countMetersByTv(@Param("lpDataItemId") Long lpDataItemId, @Param("meterIds") List<Long> meterId, @Param("startTv") Long startTv, @Param("endTv") Long endTv);

    List<RdMeterReadsLp> getPageList(@Param("lpDataItemId") Long lpDataItemId, @Param("meterId") Long meterId, @Param("subDataItems") List<Long> subDataItems, @Param("startTv") Long startTv, @Param("endTv") Long endTv);

    List<RdMeterReadsLp> getLimitList(@Param("lpDataItemId") Long lpDataItemId, @Param("meterIds") List meterId, @Param("subDataItems") List<Long> subDataItems, @Param("startTv") Long startTv, @Param("endTv") Long endTv, @Param("offset") Integer offset, @Param("limit") Integer limit);

    List<Long> getPagedTv(@Param("lpDataItemId") Long lpDataItemId, @Param("meterId") Long meterId, @Param("startTv") Long startTv, @Param("endTv") Long endTv, @Param("start") int start, @Param("end") int end);

    List<String> getCalculateRatioSubDataList();

    List<RdMeterReadsLp> getRdMeterReadsLp(@Param("meterId") Long meterId, @Param("lpDataItemId") Long lpDataItemId, @Param("subDataItemId") Long subDataItemId, @Param("startTv") Long startTv, @Param("endTv") Long endTv);

    @Select("SELECT SUB_DATA_ITEM_DESCRB FROM DD_DATA_ITEM_SUB WHERE SUB_DATA_ITEM_ID = #{subDataItemId}")
    @ResultType(String.class)
    String getSubDataItemDescSubDataItemId(Long subDataItemId);

    @Select("<script>SELECT METER_ID, DATA_ITEM_ID, TV, VALUE, VALIDITY, SRC, LP_DATA_ITEM_ID, TV_UPDATE FROM RD_METER_READS_LP" +
            " WHERE DATA_ITEM_ID = #{subDataItemId} AND METER_ID IN <foreach collection=\"meterIds\" item=\"meterId\" index=\"index\" separator=\",\" open=\"(\" close=\")\">#{meterId}</foreach> AND TV BETWEEN #{startTv} AND #{endTv} </script>")
    List<RdMeterReadsLp> getListBySubDataItem(@Param("meterIds") List<Long> meterIds,@Param("subDataItemId") Long subDataItemId, @Param("startTv") Long startTv, @Param("endTv") Long endTv);


    @Select("SELECT METER_ID, DATA_ITEM_ID, TV, VALUE, VALIDITY, SRC, LP_DATA_ITEM_ID, TV_UPDATE from RD_METER_READS_LP WHERE (TV BETWEEN #{startTime} AND #{endTime}) limit #{pageSize} OFFSET #{page}")
    @ResultType(RdMeterReadsLp.class)
    List<RdMeterReadsLp> getPageDataForPgsql(@Param("startTime") Long startTime, @Param("endTime") Long endTime, @Param("pageSize") long size, @Param("page") long page);


    List<RdMeterReadsLp> getLimitListForPgsql(@Param("lpDataItemId") Long lpDataItemId, @Param("meterIds") List meterId, @Param("subDataItems") List<Long> subDataItems, @Param("startTv") Long startTv, @Param("endTv") Long endTv, @Param("offset") Integer offset, @Param("limit") Integer limit);

    List<Long> getPagedTvForPgsql(@Param("lpDataItemId") Long lpDataItemId, @Param("meterId") Long meterId, @Param("startTv") Long startTv, @Param("endTv") Long endTv, @Param("start") int start, @Param("end") int end);

    List<RdMeterReadsLp> getFrozenDataList(@Param("meterId") Long meterId, @Param("lpDataItemId") Long lpDataItemId, @Param("tv") Long tv);

}
